package com.meida.module.arc.provider.third.controller;

import cn.hutool.core.map.MapUtil;
import cn.hutool.core.util.NumberUtil;
import cn.hutool.json.JSONObject;
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.toolkit.IdWorker;
import com.meida.common.base.entity.EntityMap;
import com.meida.common.base.utils.FlymeUtils;
import com.meida.common.mybatis.model.ResultBody;
import com.meida.common.mybatis.query.CriteriaQuery;
import com.meida.common.springmvc.base.BaseController;
import com.meida.common.utils.ApiAssert;
import com.meida.common.utils.JsonUtils;
import com.meida.common.utils.ReflectionUtils;
import com.meida.module.arc.client.entity.ArcCategory;
import com.meida.module.arc.client.entity.ArcDict;
import com.meida.module.arc.client.entity.ArcField;
import com.meida.module.arc.client.entity.ArcInfo;
import com.meida.module.arc.client.enums.ArcStatusEnum;
import com.meida.module.arc.client.enums.ArchiveEnumInteger;
import com.meida.module.arc.provider.service.*;
import com.meida.module.system.client.entity.SysCompany;
import com.meida.module.system.client.entity.SysDept;
import com.meida.module.system.provider.service.SysCompanyService;
import com.meida.module.system.provider.service.SysDeptService;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletRequest;
import java.lang.reflect.Field;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * @Description: 供第三方获取档案基础配置
 * @ClassName Api
 * @date: 2024.01.18 11:18
 * @Author: ldd
 */
@RestController
@RequestMapping("/third/api/")
public class Api extends BaseController<SysCompanyService, SysCompany> {


    /*
1、全宗
档案系统提供API：
2、字典
档案系统提供API：
3、部门
档案系统提供API：
4、档案门类
档案系统提供API：
5、档案门类字段
档案系统提供API：
     */
    @Autowired
    SysCompanyService companyService;
    @Autowired
    ArcDictService arcDictService;
    @Autowired
    SysDeptService sysDeptService;
    @Autowired
    ArcFieldService arcFieldService;
    @Autowired
    ArcCategoryService arcCategoryService;
    @Autowired
    ArcInfoService arcInfoService;
    @Autowired
    ArcOriginalService arcOriginalService;


    @ApiOperation(value = "档案全宗-列表", notes = "档案全宗列表")
    @GetMapping(value = "qzList")
    public ResultBody qzList(@RequestParam(required = false) Map params) {
        CriteriaQuery cq = new CriteriaQuery(SysCompany.class);
        cq.select("companyId", "companyName");
        List list = companyService.listMaps(cq);
        return ResultBody.ok(list);
    }

    @ApiOperation(value = "档案字典-列表", notes = "档案字典列表")
    @GetMapping(value = "dictList")
    public ResultBody dictList(@RequestParam(required = false) Map params) {

        ApiAssert.isNotEmpty("全宗不能为空", MapUtil.getLong(params, "qzId"));

        CriteriaQuery cq = new CriteriaQuery(ArcDict.class);
        cq.select("dictName", "dictCode");
        cq.eq("qzId", MapUtil.getLong(params, "qzId"));
        List list = arcDictService.listMaps(cq);
        return ResultBody.ok(list);
    }

    @ApiOperation(value = "档案部门-列表", notes = "档案部门列表")
    @GetMapping(value = "deptList")
    public ResultBody deptList(@RequestParam(required = false) Map params) {
        ApiAssert.isNotEmpty("全宗不能为空", MapUtil.getLong(params, "qzId"));

        CriteriaQuery cq = new CriteriaQuery(SysDept.class);
        cq.select("deptName", "deptCode");
        cq.eq("companyId", MapUtil.getLong(params, "qzId"));
        List list = sysDeptService.listMaps(cq);
        return ResultBody.ok(list);
    }

    @ApiOperation(value = "档案门类-列表", notes = "档案门类列表")
    @GetMapping(value = "categoryList")
    public ResultBody categoryList(@RequestParam(required = false) Map params) {
        ApiAssert.isNotEmpty("全宗不能为空", MapUtil.getLong(params, "qzId"));
        ArcCategory obj = arcCategoryService.getById(1);


        CriteriaQuery cq = new CriteriaQuery(ArcCategory.class);
        cq.select("categoryId", "cnName");
        cq.eq("qzId", MapUtil.getLong(params, "qzId"));
        cq.ne("type", 0);
        cq.ne("categoryId", 1);
        cq.likeRight("sysCode", obj.getSysCode());
        List list = arcCategoryService.listMaps(cq);
        return ResultBody.ok(list);
    }

    @ApiOperation(value = "档案门类字段-列表", notes = "档案门类字段列表")
    @GetMapping(value = "fieldList")
    public ResultBody fieldList(@RequestParam(required = false) Map params) {
        ApiAssert.isNotEmpty("档案门类不能为空", MapUtil.getLong(params, "categoryId"));

        CriteriaQuery cq = new CriteriaQuery(ArcField.class);
        cq.select("fieldCnName", "fieldName", "fieldId", "dataType", "inType", "inRequire", "inMaxLength");
        cq.eq("categoryId", MapUtil.getLong(params, "categoryId"));
        cq.eq("inShow", 1);
        cq.orderByAsc("inSeq");
        List<Map<String, Object>> list = arcFieldService.listMaps(cq);
        /*for (Map<String, Object> str : list) {
            // 1字符串2数字
            Integer dataType = MapUtil.getInt(str, "dataType");
            // 类型1文本框2数字框3日期框4下拉框5文本域6弹出框
            Integer inType = MapUtil.getInt(str, "inType");
            //必填
            Integer inRequire = MapUtil.getInt(str, "inRequire");
            //最大长度
            Integer inMaxLength = MapUtil.getInt(str, "inMaxLength");
        }*/

        return ResultBody.ok(list);
    }


    @ApiOperation(value = "同步预归档", notes = "同步预归档")
    @PostMapping(value = "syncArchive")
    public ResultBody syncArchive(@RequestBody JSONObject params) {

        ApiAssert.isNotEmpty("门类id不能为空", params.get("categoryId"));
        ApiAssert.isNotEmpty("机构id不能为空", params.get("unitId"));

        Map<String, Object> map = JSON.parseObject(params.toString(), Map.class);


        //获取门类字段
        CriteriaQuery<ArcField> fieldCriteriaQuery = new CriteriaQuery<ArcField>(ArcField.class);
        fieldCriteriaQuery.lambda().eq(ArcField::getCategoryId, params.get("categoryId"));
        List<ArcField> list = arcFieldService.list(fieldCriteriaQuery);
        Map<String, ArcField> fieldsMap = list.stream().collect(Collectors.toMap(ArcField::getFieldName, ArcField -> ArcField));
        map.forEach((key, value) -> {
            ArcField field = fieldsMap.get(key);
            if (field != null) {
                if (!"unitId".equals(field.getFieldName())) {
                    if (FlymeUtils.isNotEmpty(value)) {
                        if (field.getDataType().equals(2)) { //数字   int类型
                            if (!NumberUtil.isInteger(value.toString().trim())) {
                                ApiAssert.failure(String.format("字段[%s]数据类型为数字,导入数据[%s]为非数字或过长"
                                        , field.getFieldCnName(), value));
                            }

                        } else {//字符串   校验长度
                            if (field.getInType().equals(2)) {
                                if (!NumberUtil.isInteger(value.toString().trim())) {
                                    ApiAssert.failure(String.format("字段[%s]数据类型为数字,导入数据[%s]为非数字或过长"
                                            , field.getFieldCnName(), value));
                                }

                            }
                            if (ArchiveEnumInteger.IS_FALSE.getCode().equals(field.getIsBlob())
                                    && field.getColumnLength() < value.toString().length()) {
                                ApiAssert.failure(String.format("字段[%s]数据长度为[%s],导入数据[%s]过长"
                                        , field.getFieldCnName(), field.getColumnLength(), value));
                            }

                        }

                    }
                }
            }


        });

        ArcCategory category = this.arcCategoryService.getById(params.getLong("categoryId"));
        Long importId = IdWorker.getId();

        Field[] declaredFields = ArcInfo.class.getDeclaredFields();
        Map<String, Field> declaredFieldMap = Arrays.stream(declaredFields).collect(Collectors.toMap(Field::getName, Field -> Field));

        ArcInfo arcInfo = new ArcInfo();
        arcInfo.setCategoryId(params.getLong("categoryId"));
        arcInfo.setUnitId(params.getLong("unitId"));
        arcInfo.setQzId(category.getQzId());
        Map expandMap = new HashMap();
        map.forEach((key, value) -> {

            ArcField field = fieldsMap.get(key);
            if (field != null) {
                String setValue = null;
                if (FlymeUtils.isNotEmpty(value)) {
                    setValue = value.toString().trim();
                }
                if (!"unitId".equals(field.getFieldName())) {
                    if (2 == field.getDataType().intValue()) {//数字   int类型
                        if (!NumberUtil.isInteger(setValue)) {
                            ApiAssert.failure(String.format("字段[%s]数据类型为数字,导入数据[%s]为非数字或过长"
                                    , field.getFieldCnName(), setValue));
                        } else {
                            if (ArchiveEnumInteger.IS_TRUE.getCode().equals(field.getIsBlob())) {
                                expandMap.put(field.getFieldName(), setValue);
                            } else {
                                ReflectionUtils.setFieldValue(arcInfo, field.getFieldName(),
                                        arcInfoService.changeFieldValueType(
                                                arcInfoService.getFieldType(declaredFieldMap.get(field.getFieldName())
                                                        , "Integer")
                                                , setValue));
                            }
                        }
                    } else {//字符串   校验长度
                        if (ArchiveEnumInteger.IS_TRUE.getCode().equals(field.getIsBlob())) {
                            expandMap.put(field.getFieldName(), setValue);
                        } else {
                            ReflectionUtils.setFieldValue(arcInfo, field.getFieldName()
                                    , arcInfoService.changeFieldValueType(
                                            arcInfoService.getFieldType(declaredFieldMap.get(field.getFieldName())
                                                    , "String")
                                            , setValue));
                        }
                    }
                }
            }


        });
        arcInfoService.initArcInfoPreField(arcInfo);
        arcInfo.setStatus(ArcStatusEnum.ARC_STATUS_0.getCode());
        arcInfo.setExpand(JsonUtils.beanToJson(expandMap));
        arcInfo.setOutSideId(importId);
        arcInfo.setOriginalCount(0);

        arcInfoService.save(arcInfo);

        return ResultBody.ok(arcInfo);
    }

    @ApiOperation(value = "关联档案原文", notes = "关联档案原文")
    @PostMapping(value = "archiveOriginal")
    public ResultBody archiveOriginal(
            HttpServletRequest request,
            @RequestParam(value = "files") MultipartFile[] files,
            @RequestParam(value = "categoryId", required = false) Long categoryId,
            @RequestParam(value = "qzId", required = false) Long qzId,
            @RequestParam(value = "arcInfoId", required = false) Long arcInfoId) {

        Long[] fileIds = new Long[files.length];
        for (int i = 0; i < files.length; i++) {
            fileIds[i] = IdWorker.getId();
        }
        EntityMap map = arcOriginalService.upload(request, files, fileIds, categoryId, arcInfoId, null);

        return ResultBody.ok(map);
    }

}
